/**
 * @file    common.h
 *
 * @author  Li.Hua <lihua_338@163.com>.
 *
 * @date    2017-01-16
 *
 * @brief
 *
 * @note
 *
 * Modification history
 * ----------------------------------------------------------------------------
 * Date         Version  Author       History
 * ----------------------------------------------------------------------------
 *
 */

#ifndef __ALL_COMMON_H__
#define __ALL_COMMON_H__
#include <stdio.h>
#include <string.h>
#endif

#ifdef MERCURY
typedef signed int     ssize_t;
typedef unsigned int     size_t;

#define BCM_TICK_RATE_HZ    1000
#else
#define BCM_TICK_RATE_HZ    100
#endif
/*
 * Check at compile time that something is of a particular type.
 * Always evaluates to 1 so you may use it easily in comparisons.
 */
#define typecheck(type,x) \
    ({  type __dummy; \
        typeof(x) __dummy2; \
        (void)(&__dummy == &__dummy2); \
        1; \
    })

/*
 * Check at compile time that 'function' is a certain type, or is a pointer
 * to that type (needs to use typedef for the function type.)
 */
#define typecheck_fn(type,function) \
({	typeof(type) __tmp = function; \
	(void)__tmp; \
})

#define min(X, Y)				    \
	({ typeof (X) __x = (X);		\
		typeof (Y) __y = (Y);		\
		(__x < __y) ? __x : __y; })

#define max(X, Y)				    \
	({ typeof (X) __x = (X);		\
		typeof (Y) __y = (Y);		\
		(__x > __y) ? __x : __y; })

#define __INLINE        inline

#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x)	(sizeof(x)/sizeof((x)[0]))
#endif

#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif

#ifndef container_of
#define container_of(ptr, type, member) ((type *)((long)(ptr) - offsetof(type, member)))
#endif

int printk(const char *fmt, ...)  __attribute__ ((format (printf, 1, 2)));
#ifdef MERCURY
#define snprintf(str,n,format,...) sprintf(str,format,##__VA_ARGS__)
#define printf(format, ...) printk(format, ##__VA_ARGS__)
#define kmalloc(size) LocalAlloc(LMEM_ZEROINIT, size)
#define kfree(handle) do {if (handle!=NULL) {LocalFree(handle);handle=NULL;}} while(0)
#else
#define kmalloc(n)				malloc(n)
#define kfree(ptr)				free(ptr)
#endif

#define portDISABLE_INTERRUPTS()        do {} while(0)

#define DEBUG(fmt,arg...)               printk(fmt"\n", ##arg)

#define panic(msg) do { \
		int k;                               \
        printk("%s", msg);	                 \
        for (k = 0; configCPU_CLOCK_HZ; k ^= 1) {   \
            mdelay(50);                      \
        }		                             \
	} while (0)


#define BUG()   \
	do {        \
		portDISABLE_INTERRUPTS();		\
		printk("BUG: failure at %s:%d in %s()!\n", __FILE__, __LINE__, __FUNCTION__); \
	} while (0)


#define BUG_ON(condition)    do { if (condition) BUG(); } while(0)


typedef struct {
	const char	*name;
	int			(*init)(void);
} initcall_t;

typedef struct {
	const char	*name;
	void	(*exit)(void);
} exitcall_t;

#ifndef __attribute_used__
#define __attribute_used__			__attribute__((__used__))
#endif

#ifndef __attribute_section__
# define __attribute_section__(S)	__attribute__((section(#S)))
#endif

#define __define_initcall(level,fn) \
        const initcall_t __initcall_##fn __attribute_used__ \
        __attribute__((section("initcall" #level "init"))) = \
        { #fn, fn, };

#define core_initcall(fn)		__define_initcall(1,fn)
#define postcore_initcall(fn)	__define_initcall(2,fn)
#define arch_initcall(fn)		__define_initcall(3,fn)
#define subsys_initcall(fn)		__define_initcall(4,fn)
#define fs_initcall(fn)			__define_initcall(5,fn)
#define device_initcall(fn)		__define_initcall(6,fn)
#define late_initcall(fn)		__define_initcall(7,fn)

#if defined(CFG_PC_SIMULATE)
   #include <stdlib.h>

#define simple_strtol           strtol
#define simple_strtoul          strtoul
#endif


#endif /* __ALL_COMMON_H__ */


